package com.iot.ammeter.service.impl.web.pay;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iot.ammeter.dto.web.degree.DegreeDetailDTO;
import com.iot.ammeter.dto.web.pay.BalanceDTO;
import com.iot.ammeter.dto.web.pay.PayDetailDTO;
import com.iot.ammeter.entity.android.user.AppUser;
import com.iot.ammeter.exception.BusinessExceptions;
import com.iot.ammeter.mapper.web.pay.PayMapper;
import com.iot.ammeter.query.web.pay.DegreeQuery;
import com.iot.ammeter.query.web.pay.PayQuery;
import com.iot.ammeter.service.android.user.AppUserService;
import com.iot.ammeter.service.web.pay.PayService;
import com.iot.ammeter.utils.SnowFlakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @ClassName: PayServiceImpl
 * @Author: Basil
 * @Date: 2022/1/6 上午9:28
 * @Version: 1.0
 * @Description: 充值管理服务实现类
 **/
@Service
@Slf4j
public class PayServiceImpl extends ServiceImpl<PayMapper, PayDetailDTO> implements PayService {

    private final PayMapper payMapper;
    private final AppUserService appUserService;
    private final SnowFlakeIdWorker snowFlakeIdWorker;

    public PayServiceImpl(PayMapper payMapper, AppUserService appUserService, SnowFlakeIdWorker snowFlakeIdWorker) {
        this.payMapper = payMapper;
        this.appUserService = appUserService;
        this.snowFlakeIdWorker = snowFlakeIdWorker;
    }

    /**
     * 获取缴费明细列表
     *
     * @param page     页码
     * @param pageSize 每页数量
     * @param payQuery 查询条件
     * @return 缴费明细列表集合
     */
    @Override
    public IPage<PayDetailDTO> payDetailList(int page, int pageSize, PayQuery payQuery) {
        /**
         * 翻页对象
         */
        Page<PayDetailDTO> pages = new Page<>(page, pageSize);
        /**
         * 查询
         */
        IPage<PayDetailDTO> iPage = payMapper.listPayDetail(pages, payQuery);
        return iPage;
    }

    /**
     * 给app端用户充值
     *
     * @param appUserId      app用户id
     * @param rechargeAmount 充值金额
     * @return int
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int rechargeForAppUser(String appUserId, BigDecimal rechargeAmount) {
        /**
         * 查询 app用户是否存在
         */
        AppUser appUserFromDb = appUserService.getById(appUserId);
        if (appUserFromDb != null) {
            //app端用户存在
            BigDecimal balance = appUserFromDb.getBalance();
            balance = balance.add(rechargeAmount).setScale(2, BigDecimal.ROUND_UNNECESSARY);
            appUserFromDb.setBalance(balance);
            appUserFromDb.setUpdateTime(LocalDateTime.now());
            //更新app用户信息
            appUserService.saveOrUpdate(appUserFromDb);

            //TODO: 待更改，插入的表是tb_balance还是tb_recharge_balance
            //更新充值记录
            BalanceDTO balanceToDb = new BalanceDTO();
            String balanceToDbId = String.valueOf(snowFlakeIdWorker.nextId());
            balanceToDb.setBalanceId(balanceToDbId);
            balanceToDb.setAppUserId(appUserId);
            balanceToDb.setBalanceAmount(rechargeAmount);
            balanceToDb.setPayment("1");
            balanceToDb.setBalanceTime(LocalDateTime.now());
            balanceToDb.setCreateTime(LocalDateTime.now());
            balanceToDb.setUpdateTime(LocalDateTime.now());

            int result = payMapper.saveBalance(balanceToDb);
            return result > 0 ? 1 : 0;
        }
        return 0;
    }

    @Override
    public Map<String, Object> degreeDetails(DegreeQuery degreeQuery) {
        List<DegreeDetailDTO> list = payMapper.degreeDetails(degreeQuery);
        Map<String, Object> map = new HashMap<String, Object>();
        if (StrUtil.hasBlank(degreeQuery.getSchoolName())) {
            throw new BusinessExceptions("学校名称不能为空。");
        }
        if (StrUtil.hasBlank(degreeQuery.getCampusId())) {
            //校区id 为空 查询各个校区的电量总和。
            Map<String, DoubleSummaryStatistics> collect = list.stream().collect(Collectors.groupingBy(DegreeDetailDTO::getCampusName, Collectors.summarizingDouble(DegreeDetailDTO::getDegree)));
            map.put("campus", collect);
            return map;
        }

        /**
         * 计算流程：
         *          1.如果没有月份，同月份，不同设备的电量相加。
         *          2.如果有月份，同一天，不同设备的电量相加。
         */
        if (degreeQuery.getMonth() == null) {
            //1.如果没有月份，同月份，不同设备的电量相加。
            Map<Integer, DoubleSummaryStatistics> dataByMonth = list.stream().collect(Collectors.groupingBy(DegreeDetailDTO::getMonth, Collectors.summarizingDouble(DegreeDetailDTO::getDegree)));
            map.put("year", dataByMonth);
        } else {
            //2.如果有月份，同一天，不同设备的电量相加。
            Map<Integer, DoubleSummaryStatistics> collect = list.stream().collect(Collectors.groupingBy(DegreeDetailDTO::getDay, Collectors.summarizingDouble(DegreeDetailDTO::getDegree)));
            map.put("month", collect);
        }

        return map;
    }

}